package cn.tedu.toa.management.shiro.realm.config;

import cn.tedu.toa.management.shiro.realm.LoginRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    /**
     * 将LoginRealm实例交给Spring管理
     * @return
     */
    @Bean
    public LoginRealm loginRealm(){
        return new LoginRealm();
    }

    /**
     * 将LoginRealm实例交给SecurityManager对象给管理
     *
     * @return
     */
    @Bean
    public SecurityManager securityManager(){
        //得到SecurityManager对象
        DefaultWebSecurityManager securityManager= new DefaultWebSecurityManager();
        //将LoginRealm实例交给SecurityManager对象
        securityManager.setRealm(loginRealm());
        //返回SecurityManager对象
        return securityManager;
    }

    /**
     * 有一些资源需要认证后才可以访问，有一些资源（静态资源）可以允许匿名访问，
     * 配置 shiro过滤器链，实现拦截请求路径，未认证时，无法访问网站内部
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        //创建ShiroFilterFactoryBean
        ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
        /**
         * 使用map集合保存 需要拦截 和放行的路径  定义拦截的路径
         *  key 是拦截路径  value 是拦截还是放行 固定值
         *  anon: 可以匿名访问   authc认证后才能访问  logout 登出(shiro提供)
         *  添加路径时,需要先添加可以匿名访问的,剩余的均为需要热证后才可访问,所以map集合中保存的数据是有序的
         *  LinkedHashMap
         */
        Map<String,String> filterChainDefinitionMap= new LinkedHashMap<>();
        filterChainDefinitionMap.put("/bower_components/**","anon");
        filterChainDefinitionMap.put("/build/**","anon");
        filterChainDefinitionMap.put("/dist/**","anon");
        filterChainDefinitionMap.put("/plugins/**","anon");
        //登录请求
        filterChainDefinitionMap.put("/sys-users/login","anon");
        //登出
        filterChainDefinitionMap.put("/logout","logout");
        //官网页面权限放行
        filterChainDefinitionMap.put("/front/**","anon");
        filterChainDefinitionMap.put("/images/**","anon");
        filterChainDefinitionMap.put("/index","anon");
        filterChainDefinitionMap.put("/","anon");
        filterChainDefinitionMap.put("/keyServices","anon");
        filterChainDefinitionMap.put("/breSources","anon");
        filterChainDefinitionMap.put("/news","anon");
        filterChainDefinitionMap.put("/newsCenter","anon");
        filterChainDefinitionMap.put("/aboutUs","anon");
        filterChainDefinitionMap.put("/service","anon");
        //放开请求路径
        filterChainDefinitionMap.put("/f-keyservices/getMenus","anon");
        filterChainDefinitionMap.put("/f-bresources/getBresources","anon");
        filterChainDefinitionMap.put("/f-infocompany/aboutUs","anon");
        filterChainDefinitionMap.put("/f-news/**","anon");
        //其他资源认证后才可访问
        filterChainDefinitionMap.put("/**","authc");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        //需要认证时,发起一下请求,跳转到登录页面
        bean.setLoginUrl("/loginPage");
        bean.setSuccessUrl("/admin");
        return bean;
    }

    @Bean(name="lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        // 对Shiro中的Bean的生命周期进行管理
        return new LifecycleBeanPostProcessor();
    }
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
                = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }



}
